package com.yoga.api;

import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wf.captcha.SpecCaptcha;
import com.yoga.model.Account;
import com.yoga.model.Admin;
import com.yoga.service.AdminService;
import com.yoga.service.UploadService;
import com.yoga.utils.AliOSS;
import com.yoga.utils.JsonResult;
import com.yoga.utils.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jasypt.util.password.StrongPasswordEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @author yan
 * @date 2025/8/18
 */
@RestController
@RequestMapping(value = "/api/v1/admin", produces = MediaType.APPLICATION_JSON_VALUE)
public class AdminApi {

    private AdminService adminService;
    private AliOSS aliOSS;
    @Autowired
    public void setAliOSS(AliOSS aliOSS) {
        this.aliOSS = aliOSS;
    }

    @Autowired
    public void setAdminService(AdminService adminService) {
        this.adminService = adminService;
    }

    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    public void setRedisTemplate(RedisTemplate<Object, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    private static final StrongPasswordEncryptor passwordGenerator = new StrongPasswordEncryptor();
    @Value("${jwt.secret}")
    private String secret;

    //查询
    @GetMapping
    public ResponseEntity<JsonResult<?>> findAll(Integer pageNo, Integer pageSize, Admin admin){
        Page<Admin> page = new Page<>(pageNo,pageSize);
        page = this.adminService.findAll(page,admin);
        //System.out.println(page);
        return ResponseEntity.ok(JsonResult.success(page));
    }

    //删除
    @DeleteMapping
    public ResponseEntity<JsonResult<?>> deleteById(@RequestBody Integer id){
        boolean success = this.adminService.deleteById(id);
        return ResponseEntity.ok(JsonResult.success(success));
    }

    //添加
    @PostMapping
    public ResponseEntity<JsonResult<?>> add(@RequestBody Admin admin){
        String password = admin.getPassword();
        if(password!=null){
            String newEnPassword = passwordGenerator.encryptPassword(password);
            admin.setPassword(newEnPassword);
        }
        boolean success = this.adminService.add(admin);
        if(success){
            return ResponseEntity.ok(JsonResult.success(admin));
        }else {
            return ResponseEntity.ok(JsonResult.fail("添加失败"));
        }
    }

    //修改
    @PutMapping
    public ResponseEntity<JsonResult<?>> edit(@RequestBody Admin admin){
        boolean success = this.adminService.update(admin);
        if(success){
            return ResponseEntity.ok(JsonResult.success(admin));
        }else {
            return ResponseEntity.ok(JsonResult.fail("修改失败"));
        }
    }

    @PostMapping("/avatar")
    public ResponseEntity<JsonResult<?>> uploadAvatar(MultipartFile file) throws IOException {
        String url = this.aliOSS.upload(file,"admin/");
        return ResponseEntity.ok(JsonResult.success(url));
    }


    @GetMapping("/captcha")
    public void getCaptcha(String id,HttpServletRequest req, HttpServletResponse resp) throws IOException {
        SpecCaptcha captcha = new SpecCaptcha(140, 40, 4);
        resp.setContentType("image/gif");
        resp.setHeader("Pragma", "No-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", 0);
        //req.getSession().setAttribute("captcha", captcha.text().toLowerCase());//这个是往session里面放
        redisTemplate.opsForValue().set("captcha-"+id, captcha.text().toLowerCase(), Duration.ofMinutes(3));
        captcha.out(resp.getOutputStream());
    }

    @PostMapping("/login")
    public ResponseEntity<JsonResult<?>> login(@RequestBody Account account){
        String captcha = (String) redisTemplate.opsForValue().get("captcha-"+account.getCaptchaId());
        if (!account.getCaptcha().equals(captcha)){
            return ResponseEntity.ok(JsonResult.fail("验证码错误"));
        }
        Admin admin = this.adminService.findByUsername(account.getUsername());
        if (admin == null){
            return ResponseEntity.ok(JsonResult.fail("用户不存在"));
        }
        //验证密码
        boolean flag = passwordGenerator.checkPassword(account.getPassword(), admin.getPassword());
        if (!flag){
            return ResponseEntity.ok(JsonResult.fail("密码错误"));
        }
        //颁发jwt
        String jwt = JwtUtil.createJwt(UUID.randomUUID().toString(), admin.getUsername(), Map.of("username",admin.getUsername(),"Id",admin.getId()),
                LocalDateTime.now().plusMinutes(30),secret);
        return ResponseEntity.ok(JsonResult.success(jwt));
    }

    @PutMapping("/password")
    public ResponseEntity<JsonResult<?>> editPassword(@RequestBody Map<String, String>  params,HttpServletRequest req){
        String username = params.get("username");
        String oldPassword = params.get("oldPassword");
        String newPassword = params.get("newPassword");
        String confirmPassword = params.get("confirmPassword");
        if (!newPassword.equals(confirmPassword)){
            return ResponseEntity.ok(JsonResult.fail("两次密码不一致"));
        }
        Admin admin = this.adminService.findByUsername(username);
        if(admin==null){
            return ResponseEntity.ok(JsonResult.fail("用户不存在"));
        }
        boolean flag = passwordGenerator.checkPassword(oldPassword,admin.getPassword());
        if(!flag){
            return ResponseEntity.ok(JsonResult.fail("旧密码错误"));
        }
        String newEnPassword = passwordGenerator.encryptPassword(newPassword);
        admin.setPassword(newEnPassword);
        boolean success = this.adminService.update(admin);
        if(success){
            String jwt = req.getHeader("jwt");
            if (jwt != null) {
                // 获取JWT的剩余有效时间
                try {
                    DecodedJWT decodedJWT = JWT.decode(jwt);
                    //计算剩余有效时间
                    long ttl = decodedJWT.getExpiresAt().getTime() - System.currentTimeMillis();
                    if (ttl > 0) {
                        // 将JWT加入黑名单，设置相同的过期时间
                        redisTemplate.opsForValue().set("jwt:blacklist:" + jwt, "true", Duration.ofMillis(ttl));
                    }
                } catch (Exception e) {
                    // 解析失败则忽略
                }
            }
            return ResponseEntity.ok(JsonResult.success("修改成功"));
        }else {
            return ResponseEntity.ok(JsonResult.fail("修改失败"));
        }

    }
}
